'''
Created on Aug 19, 2013

@author: Cihat Basol
'''

import os
import logging

from flask import request, redirect, url_for
from flask.ext.login import (login_user, logout_user, login_required,
                             current_user)
from flask.helpers import make_response
from flask.json import jsonify
from flask.templating import render_template
import pymongo

from dexen.common import db, task
from dexen.server.frontend import app, login_mgr, form as dexen_form, proxy


logger = logging.getLogger(__name__)

_server_backend = None
_user_mgr = None
_db_client = None


@login_mgr.user_loader
def load_user(user_id):
    return _user_mgr.get_user(id=user_id)


@app.route("/")
def index():
    if not current_user.is_authenticated():
        logger.debug("Current user is not authenticated redirecting to login page")
        return redirect(url_for("login"))
    logger.debug("Current user is authenticated: %s", current_user.username) # @UndefinedVariable
    with open(os.path.join(app.root_path, "app", "views", "index2.html")) as html_file:
        html_content = html_file.read()
    return make_response(html_content)


@app.route("/register", methods=["GET", "POST"])
def register():
    if request.method == "POST": # @UndefinedVariable
        form = dexen_form.RegistrationForm(_user_mgr)
        if form.validate_on_submit():
            _user_mgr.register_user(form.username.data, form.password.data)
            return redirect(url_for("login"))
        logger.debug("Errors %s", form.errors)
        return "Registration failed"
    return render_template("register.html")


@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST": # @UndefinedVariable
        form = dexen_form.LoginForm(_user_mgr)
        if form.validate_on_submit():
            login_user(form.get_user())
            logger.debug("%s Logged in successfully", current_user.username) # @UndefinedVariable
            return redirect(url_for("index")) # @UndefinedVariable
        print "Login failed. Errors", form.errors
        return redirect(url_for("login"))
    print "Getting login.html"
    return render_template("login.html")


@app.route("/logout")
@login_required
def logout():
    print "I am logging out user:", current_user.username # @UndefinedVariable
    logout_user()
    assert current_user.is_authenticated() == False
    print "I am redirecting to login page again"
    return redirect(url_for("index"))


@app.route("/deneme")
@login_required
def deneme():
    return "Deneme "


@app.route("/upload_file/<job_name>", methods=["POST"])
@login_required
def upload_file(job_name):
    file_ = request.files['file'] # @UndefinedVariable
    logger.info("Uploading file %s for %s", file_.filename, job_name)
    #db_name = GetUserDBName(current_user.username) # @UndefinedVariable
    #logger.debug("Accessing username's db: %s", db_name)
    file_mgr = db.FileManager(_db_client, current_user.username) # @UndefinedVariable
    file_mgr.put_data(job_name, file_.filename, file_.read())
    return redirect(url_for("index"))


@app.route("/executions/<job_name>", methods=["GET"])
@login_required
def get_executions(job_name):
    last_update = request.args.get("last_update", 0) # @UndefinedVariable
    last_update = float(last_update)
    execution_mgr = db.ExecutionManager(_db_client, current_user.username,  # @UndefinedVariable
                                        job_name)
    executions = execution_mgr.get_executions(last_update)
    return jsonify(executions=executions)


@app.route("/jobs", methods=["GET"])
@login_required
def get_jobs():
    logger.info("getting jobs")
    jobs = _server_backend.get_jobs(current_user.username) # @UndefinedVariable
    return jsonify(jobs=jobs)


@app.route("/create_job/<job_name>", methods=["POST"])
@login_required
def create_job(job_name):
    logger.info("%s is created.", job_name)
    _server_backend.create_job(current_user.username, job_name) # @UndefinedVariable
    return "%s created.\n"%(job_name,)


@app.route("/delete_job/<job_name>", methods=["POST"])
@login_required
def delete_job(job_name):
    logger.info("%s is deleted.", job_name)
    _server_backend.delete_job(current_user.username, job_name) # @UndefinedVariable
    return "%s deleted.\n"%(job_name,)


@app.route("/run_job/<job_name>", methods=["POST"])
@login_required
def run_job(job_name):
    logger.info("%s is created.", job_name)
    _server_backend.run_job(current_user.username, job_name) # @UndefinedVariable
    return "Running %s.\n"%(job_name,)


@app.route("/stop_job/<job_name>", methods=["POST"])
@login_required
def stop_job(job_name):
    _server_backend.stop_job(current_user.username, job_name) # @UndefinedVariable
    return "Stopping %s.\n"%(job_name,)


@app.route("/register_task/<job_name>", methods=["POST"])
@login_required
def register_task(job_name):
    task_obj = task.TaskFromJSON(request.json) # @UndefinedVariable
    logger.info("Registering %s %s", job_name, task_obj.name)
    _server_backend.register_task(current_user.username, job_name, task_obj) # @UndefinedVariable
    return jsonify({})


@app.route("/deregister_task/<job_name>/<task_name>", methods=["POST"])
@login_required
def deregister_task(job_name, task_name):
    logger.info("Deregistering %s %s.", job_name, task_name)
    _server_backend.deregister_task(current_user.username, job_name, task_name) # @UndefinedVariable
    return "Deregistering %s %s.\n"%(job_name, task_name)


def start_webserver(backend_addr, db_addr):
    global _server_backend, _user_mgr, _db_client
    _db_client = pymongo.MongoClient(db_addr.ip, db_addr.port)
    _server_backend = proxy.ServerBackendProxy(backend_addr)
    _user_mgr = db.UserManager()
    app.run(threaded=True, debug=True, use_reloader=False)
    """
    d = wsgiserver.WSGIPathInfoDispatcher({'/': app})
    server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 5000), d)
    try:
        server.start()
    except:
        server.stop()
    """
